(* Mathematica package *)

BeginPackage["MultiAgent`"]
(* Exported symbols added here with SymbolName::usage *) 

makeExperiment			::usage = "";
initMultiAgentExchange	::usage = "Function for initialising Multi Agent system (Mono/Multi) ";
simulationNumber		::usage = "Current simulation index";
refreshConfig			::usage = "Loads params from config file";

Options[initMultiAgentExchange] =
    Join[
        { LoadFrom -> 0, SystemType -> MoneySystem }, 
     	Options[testCurrencyMarket],
     	Options[createAgents]
	];

Begin["`Private`"]

defConfigFile = "test.conf.m";

refreshConfig[] :=
	ReadList[ DirectoryName@FindFile["MultiAgent`"] <> FileNameJoin[{"..", "Scripts", defConfigFile}] ];
	
	
makeExperiment[simsN_] :=
	Module[{i},
		initMultiAgentExchange[False];
		
		openConn[];
		createSettingsRecord[];
		
		For[i = 1, i <= simsN, i++,
			simulationNumber = i;
			initMultiAgentExchange[True];
			createSimulationRecord[];
			
			runExchange[];	
		];
		
		Print["Finished! (", simsN, ") simulations"];
	];

initMultiAgentExchange[needDB_:False, OptionsPattern[]] :=
    Module[ {opts, fself = initMultiAgentExchange, source = OptionValue[LoadFrom], newMarkets, MakeMarketsFunc, newAgents},
        (* opts = #->StringTrim[OptionValue@#, RegularExpression["^(" <> String@Context@# <> ")?*"]] &/@ Options[fself][[All, 1]]; *)
        opts = #->OptionValue@# &/@ Options[fself] [[All, 1]];
        
        Switch[source,
        	0 (* read parameters from "test.conf.m" *)
        	,
            	refreshConfig[];       		
        	,
        	_ (* settings id from DB *)
        	,
				loadSettingsByIndex[];
        ];
        
        opts = First /@ GatherBy[PARAMS ~Join~ opts, First];
        		If[needDB,
        			Print["- Simulation #", simulationNumber, " started -"],
        			Print[opts] 
        		]; 
        
        initHistoryVars[];
        initExchange[needDB];
        initAgents[];
        initMarkets[];
        
        evaluateWithOpts[createProducts, opts];
        
        newAgents = evaluateWithOpts[createAgents, opts];
        addAgent /@ newAgents;
        
        MakeMarketsFunc = If[OptionValue[SystemType] == "Mono", monoCurrencyMarkets, multiCurrencyMarkets]; 
        newMarkets = evaluateWithOpts[MakeMarketsFunc, opts];
        addMarket /@ newMarkets;
        
        setAgentsParams[];
        
        initAgentsGoods[];        
    ]
    
End[]

EndPackage[]